<template>
<div id="cascade-selector">
    <div 
        class="selector" 
        @click="handleClickShowSelector"
    >{{selectedText.join(" / ")}}</div>
    <div class="item-selector" v-show="showSelector">
        <ul 
            class="ul" 
            @mouseout="handleUlEvent" 
            @mouseover="handleUlEvent" 
            @click="handleUlEvent"
            data-ul='1'
        >
            <li 
                v-for="item in firstCasadeList" 
                :key="item[childid]" 
                class="li" 
                :title="item[name]"
                :data-cid="item[childid]"
            >{{item[name]}}</li>
        </ul>
        <ul 
            v-show="firstPid && secondCasadeList.length > 0" 
            :class="['ul', {'translate-right': firstPid}]" 
            @mouseover="handleUlEvent"
            @click="handleUlEvent"
            data-ul='2'
        >
            <li 
                v-for="item in secondCasadeList" 
                :key="item[childid]" 
                class="li" 
                :title="item[name]"
                :data-cid="item[childid]"
            >{{item[name]}}</li>
        </ul>
        <ul 
            v-show="firstPid && secondPid && threeCasadeList.length > 0" 
            :class="['ul', {'translate-right2': secondPid}]" 
            @click="handleUlEvent"
            data-ul='3'
        >
            <li 
                v-for="item in threeCasadeList" 
                :key="item[childid]" 
                class="li" 
                :title="item[name]"
                :data-cid="item[childid]"
            >{{item[name]}}</li>
        </ul>
    </div>
</div>
</template>

<script>
export default {
    name: 'myCascadeSelector',
    props: {
        list: [Array],
        pid: {
            type: String,
            default: 'cat_pid'
        },
        childid: {
            type: String,
            default: 'cat_id'
        },
        level: {
            type: String,
            default: 'cat_level'
        },
        name: {
            type: String,
            default: 'cat_name'
        }
    },
    data() {
        return {
            selectedText: [],
            selectedCid: [],
            showSelector: false,
            firstPid: '',
            secondPid: ''
        }
    },
    methods: {
        handleClickShowSelector() {
            this.showSelector = !this.showSelector
            this.firstPid = ''
            this.secondPid = ''
            this.selectedText = []
            this.selectedCid = []
            this.$emit('cascade-event', {
                selectedText: this.selectedText, 
                selectedCid: this.selectedCid
            })
        },
        handleUlEvent(e) {
            if(e.target.constructor === HTMLUListElement) return;
            const u = e.target.parentNode.dataset.ul
            if(u === '1') {
                switch(e.type) {
                    case 'click':
                        this.selectedText = this.selectedText.slice(0, 1)
                        this.selectedCid = this.selectedCid.slice(0, 1)
                        this.showSelector = false
                        this.firstPid = ''
                        this.secondPid = ''
                        this.$emit('cascade-event', {
                            selectedText: this.selectedText, 
                            selectedCid: this.selectedCid
                        })
                        break;
                    case 'mouseover':
                        this.firstPid = e.target.dataset.cid
                        this.selectedText.splice(0, 1, e.target.textContent)
                        this.selectedCid.splice(0, 1, this.firstPid)
                    case 'mouseout':
                        this.secondPid = ''
                }
            } else if(u === '2') {
                switch(e.type) {
                    case 'click':
                        this.selectedText = this.selectedText.slice(0, 2)
                        this.selectedCid = this.selectedCid.slice(0, 2)
                        this.showSelector = false
                        this.firstPid = ''
                        this.secondPid = ''
                        this.$emit('cascade-event', {
                            selectedText: this.selectedText, 
                            selectedCid: this.selectedCid
                        })
                        break;
                    case 'mouseover':
                        this.secondPid = e.target.dataset.cid
                        this.selectedText.splice(1, 1, e.target.textContent)
                        this.selectedCid.splice(1, 1, this.secondPid)
                }
            } else if(u === '3' && e.type === 'click') {
                this.threePid = e.target.dataset.cid
                this.selectedCid.splice(2, 1, this.threePid)
                this.selectedText.splice(2, 1, e.target.textContent)
                this.showSelector = false
                this.firstPid = ''
                this.secondPid = ''
                this.$emit('cascade-event', {
                    selectedText: this.selectedText, 
                    selectedCid: this.selectedCid
                })
            }
        },
        treeToList(tree) {
            let data = JSON.parse(JSON.stringify(tree))
            return data.reduce((pre, curr) => {
                let arr = []
                let newObj = {}
                if(curr.children?.length > 0) {
                    arr = arr.concat(this.treeToList(curr.children))
                }
                for (const key in curr) {
                    if(key !== 'children') {
                        newObj[key] = curr[key]
                    }
                }
                pre.push(newObj)
                return pre.concat(arr)
            }, [])
        }
    },
    computed: {
        firstCasadeList() {
            let list = this.treeToList(this.list)
            return list.filter(item => Number(item[this.level]) === 0);
        },
        secondCasadeList() {
            let list = this.treeToList(this.list)
            return list.filter(item => 
                Number(item[this.pid]) === Number(this.firstPid) && Number(item[this.level]) === 1
            );
        },
        threeCasadeList() {
            let list = this.treeToList(this.list)
            return list.filter(item => 
                Number(item[this.pid]) === Number(this.secondPid) && Number(item[this.level]) === 2
            );
        }
    }
}
</script>

<style scoped>
#cascade-selector {
    position: relative;
    width: 300px;
}
.selector {
    overflow: hidden;
    width: 200px;
    height: 32px;
    text-align: center;
    line-height: 32px;
    padding: 0 6px;
    margin-bottom: 3px;
    border: 1px solid #ccc;
    border-radius: 6px;
    white-space: nowrap;
    text-overflow: ellipsis;
    cursor: pointer;
    transition: background-color 0.32s;
}
.selector:hover {
    background-color: #eee;
}
.item-selector {
    overflow: hidden;
    position: absolute;
    top: 39px;
    height: 180px;
    background-color: #eee;
    z-index: 10;
}
.ul {
    overflow: auto;
    float: left;
    width: 100px;
    height: 180px;
    text-align: center;
    border: 1px solid #ccc;
    border-radius: 6px;
    box-sizing: border-box;
}
.translate-right {
    left: 100px;
}
.translate-right2 {
    left: 200px;
}
.ul::-webkit-scrollbar {
    display: none;
}
.li {
    overflow: hidden;
    width: 100%;
    height: 34px;
    line-height: 34px;
    padding: 0 6px;
    white-space: nowrap;
    text-overflow: ellipsis;
    border-bottom: 1px solid #ccc;
    box-sizing: border-box;
    cursor: pointer;
    transition: background-color 0.32s;
}
.li:hover {
    background-color: rgba(204, 204, 204, 0.8);
}
</style>